/*
 * Copyright [2022] [https://www.xiaonuo.vip]
 *
 * Snowy采用APACHE LICENSE 2.0开源协议，您在使用过程中，需要注意以下几点：
 *
 * 1.请不要删除和修改根目录下的LICENSE文件。
 * 2.请不要删除和修改Snowy源码头部的版权声明。
 * 3.本项目代码可免费商业使用，商业使用请保留源码和相关描述文件的项目出处，作者声明等。
 * 4.分发源码时候，请注明软件出处 https://www.xiaonuo.vip
 * 5.不可二次分发开源参与同类竞品，如有想法可联系团队xiaonuobase@qq.com商议合作。
 * 6.若您的项目无法满足以上几点，需要更多功能代码，获取Snowy商业授权许可，请在官网购买授权，地址为 https://www.xiaonuo.vip
 */
package cn.lixunims.ims.modular.order.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollStreamUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONObject;
import cn.lixunims.ims.modular.basics.entity.ImsCustomer;
import cn.lixunims.ims.modular.basics.entity.ImsProduct;
import cn.lixunims.ims.modular.basics.entity.ImsSupplier;
import cn.lixunims.ims.modular.basics.entity.ImsWarehouse;
import cn.lixunims.ims.modular.basics.service.ImsCustomerService;
import cn.lixunims.ims.modular.basics.service.ImsProductService;
import cn.lixunims.ims.modular.basics.service.ImsSupplierService;
import cn.lixunims.ims.modular.basics.service.ImsWarehouseService;
import cn.lixunims.ims.modular.basics.service.impl.ImsProductServiceImpl;
import cn.lixunims.ims.modular.bill.entity.ImsBillHeader;
import cn.lixunims.ims.modular.bill.service.impl.ImsBillHeaderServiceImpl;
import cn.lixunims.ims.modular.inventory.entity.ImsInventoryCheck;
import cn.lixunims.ims.modular.inventory.service.impl.ImsInventoryCheckServiceImpl;
import cn.lixunims.ims.modular.order.entity.ImsOrderDetail;
import cn.lixunims.ims.modular.order.service.ImsOrderDetailService;
import cn.lixunims.ims.modular.inventory.service.ImsInventoryChangeLogService;
import cn.lixunims.ims.modular.inventory.service.ImsRealTimeInventoryService;
import cn.lixunims.sys.api.SysUserApi;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.conditions.query.QueryChainWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import cn.lixunims.common.enums.CommonSortOrderEnum;
import cn.lixunims.common.exception.CommonException;
import cn.lixunims.common.page.CommonPageRequest;
import cn.lixunims.ims.modular.order.entity.ImsOrderHeader;
import cn.lixunims.ims.modular.order.mapper.ImsOrderHeaderMapper;
import cn.lixunims.ims.modular.order.param.ImsOrderAddParam;
import cn.lixunims.ims.modular.order.param.ImsOrderHeaderEditParam;
import cn.lixunims.ims.modular.order.param.ImsOrderHeaderIdParam;
import cn.lixunims.ims.modular.order.param.ImsOrderHeaderPageParam;
import cn.lixunims.ims.modular.order.service.ImsOrderHeaderService;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;

/**
 * 出入库单据头Service接口实现类
 *
 * @author YouDong
 * @date  2024/09/19 14:28
 **/
@Service
public class ImsOrderHeaderServiceImpl extends ServiceImpl<ImsOrderHeaderMapper, ImsOrderHeader> implements ImsOrderHeaderService {


    @Autowired
    private ImsSupplierService imsSupplierService;
    @Autowired
    private ImsWarehouseService imsWarehouseService;
    @Autowired
    private ImsCustomerService imsCustomerService;

    @Autowired
    private ImsOrderHeaderService imsOrderHeaderService;
    @Autowired
    private ImsOrderDetailService imsOrderDetailService;
    @Autowired
    private ImsRealTimeInventoryService realTimeInventoryService;
    @Autowired
    private ImsProductServiceImpl imsProductServiceImpl;
    @Autowired
    private ImsInventoryChangeLogService imsInventoryChangeLogService;
    @Autowired
    private ImsRealTimeInventoryService imsRealTimeInventoryService;
    @Autowired
    private SysUserApi sysUserApi;
    @Autowired
    private ImsProductService imsProductService;
    @Autowired
    private ImsBillHeaderServiceImpl imsBillHeaderServiceImpl;
    @Autowired
    private ImsInventoryCheckServiceImpl imsInventoryCheckServiceImpl;


    @Override
    public Page<ImsOrderHeader> page(ImsOrderHeaderPageParam imsOrderHeaderPageParam) {
        QueryWrapper<ImsOrderHeader> queryWrapper = new QueryWrapper<ImsOrderHeader>().checkSqlInjection();

        queryWrapper.lambda().like(StrUtil.isNotBlank(imsOrderHeaderPageParam.getBillOrderNo()), ImsOrderHeader::getBillOrderNo, imsOrderHeaderPageParam.getBillOrderNo());
        queryWrapper.lambda().like(StrUtil.isNotBlank(imsOrderHeaderPageParam.getBillType()), ImsOrderHeader::getBillType, imsOrderHeaderPageParam.getBillType());
        // 状态
        if (StrUtil.isNotBlank(imsOrderHeaderPageParam.getBillStatus())) {
            queryWrapper.lambda().eq(ImsOrderHeader::getBillStatus, imsOrderHeaderPageParam.getBillStatus());
        } else {
            queryWrapper.lambda().eq(ImsOrderHeader::getBillStatus, 1);
        }

        if(ObjectUtil.isAllNotEmpty(imsOrderHeaderPageParam.getSortField(), imsOrderHeaderPageParam.getSortOrder())) {
            CommonSortOrderEnum.validate(imsOrderHeaderPageParam.getSortOrder());
            queryWrapper.orderBy(true, imsOrderHeaderPageParam.getSortOrder().equals(CommonSortOrderEnum.ASC.getValue()),
                    StrUtil.toUnderlineCase(imsOrderHeaderPageParam.getSortField()));
        } else {
            queryWrapper.lambda().orderByDesc(ImsOrderHeader::getBillDate);
        }
        Page<ImsOrderHeader> page = this.page(CommonPageRequest.defaultPage(), queryWrapper);
        List<ImsOrderHeader> records = page.getRecords();
        if (records.isEmpty()) {
            return page;
        }

        // 客户信息
        List<String> customerIds = CollStreamUtil.toList(records, ImsOrderHeader::getCustomerIds);
        List<ImsCustomer> customers;
        if (!customerIds.isEmpty()) {
            customers = imsCustomerService.lambdaQuery().in(ImsCustomer::getCustomerId, customerIds).list();
        } else {
            customers = new ArrayList<>();
        }


        // 关联供应商信息
        List<String> supplierIds = CollStreamUtil.toList(records, ImsOrderHeader::getSupplierIds);
        List<ImsSupplier> supplierList;
        if (!supplierIds.isEmpty()) {
            supplierList = imsSupplierService.lambdaQuery().in(ImsSupplier::getSupplierId, supplierIds).list();
        } else {
            supplierList = new ArrayList<>();
        }
        // 业务员
        List<String> userIds = CollStreamUtil.toList(records, ImsOrderHeader::getUserIds);
        List<JSONObject> userList = new ArrayList<>();
        if (!userIds.isEmpty()) {
            try {
                userList = sysUserApi.getUserListByIdWithException(userIds);
            } catch (Exception e) {
                // 无业务不处理
                userList = new ArrayList<>();
            }
        }



        // 批量查询关联信息
        List<JSONObject> finalUserList = userList;
        records.forEach(billHeader -> {
            // 关联供应商，客户
            if (!supplierList.isEmpty()) {
                billHeader.setSupplier(supplierList.stream().filter(imsSupplier -> imsSupplier.getSupplierId().equals(billHeader.getSupplierIds())).findFirst().orElse(null));
            }
            if (!customers.isEmpty()) {
                billHeader.setCustomer(customers.stream().filter(imsCustomer -> imsCustomer.getCustomerId().equals(billHeader.getCustomerIds())).findFirst().orElse(null));
            }
            if (!finalUserList.isEmpty()) {
                billHeader.setUser(finalUserList.stream().filter(userObj -> userObj.getStr("id").equals(billHeader.getUserIds())).findFirst().orElse(null));
            }
        });

        return page;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void add(ImsOrderAddParam imsOrderAddParam) {
        ImsOrderHeader imsOrderHeader = BeanUtil.toBean(imsOrderAddParam, ImsOrderHeader.class);
        this.save(imsOrderHeader);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void edit(ImsOrderHeaderEditParam imsOrderHeaderEditParam) {
        ImsOrderHeader imsOrderHeader = this.queryEntity(imsOrderHeaderEditParam.getBillId());
        BeanUtil.copyProperties(imsOrderHeaderEditParam, imsOrderHeader);
        this.updateById(imsOrderHeader);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void delete(ImsOrderHeaderIdParam imsOrderHeaderIdParam) {
        // 直接删除单据
        String billId = imsOrderHeaderIdParam.getBillId();
        ImsOrderHeader orderHeader = getById(billId);
        orderHeader.setBillStatus("0");
        this.updateById(orderHeader);
    }

    @Override
    public ImsOrderAddParam detail(ImsOrderHeaderIdParam imsOrderHeaderIdParam) {
        ImsOrderAddParam result = new ImsOrderAddParam();
        ImsOrderHeader imsOrderHeader = this.queryEntity(imsOrderHeaderIdParam.getBillId());
        // 关联供应商或者客户
        if (StrUtil.isNotBlank(imsOrderHeader.getSupplierIds())) {
            ImsSupplier supplier = imsSupplierService.queryEntity(imsOrderHeader.getSupplierIds());
            imsOrderHeader.setSupplier(supplier);
            imsOrderHeader.setSupplierName(supplier.getSupplierName());
        }
        if (StrUtil.isNotBlank(imsOrderHeader.getCustomerIds())) {
            ImsCustomer imsCustomer = imsCustomerService.queryEntity(imsOrderHeader.getCustomerIds());
            imsOrderHeader.setCustomer(imsCustomer);
            imsOrderHeader.setCustomerName(imsCustomer.getCustomerName());
        }
        // 业务员
        if (StrUtil.isNotBlank(imsOrderHeader.getUserIds())) {
            try {
                JSONObject userByIdWithoutException = sysUserApi.getUserByIdWithoutException(imsOrderHeader.getUserIds());
                imsOrderHeader.setUser(userByIdWithoutException);
                imsOrderHeader.setUserName(userByIdWithoutException.getStr("name"));
            } catch (Exception ignored) {
            }
        }
        // 仓库
        if (StrUtil.isNotBlank(imsOrderHeader.getWarehousingIds())) {
            ImsWarehouse warehouse = imsWarehouseService.queryEntity(imsOrderHeader.getWarehousingIds());
            imsOrderHeader.setWarehouse(warehouse);
            imsOrderHeader.setWarehouseName(warehouse.getWareName());
        }

        // 清单
        imsOrderHeader.setImsOrderDetails(imsOrderDetailService.list(new LambdaQueryWrapper<ImsOrderDetail>().eq(ImsOrderDetail::getBillId, imsOrderHeader.getBillId())));


        List<ImsOrderDetail> list = imsOrderDetailService.lambdaQuery().eq(ImsOrderDetail::getBillId, imsOrderHeader.getBillId()).list();
        // 商品名称
        for (ImsOrderDetail imsOrderDetail : list) {
            ImsProduct imsProduct = imsProductService.queryEntity(imsOrderDetail.getProductId());
            if (imsProduct != null) {
                imsOrderDetail.setProductTotalName(imsProduct.getProductCode() + "-"+imsProduct.getProductName());
            }
            if (StrUtil.isNotBlank(imsOrderDetail.getRetrievalId())) {
                ImsWarehouse byId = imsWarehouseService.getById(imsOrderDetail.getRetrievalId());
                imsOrderDetail.setWareName(byId.getWareName());
            } else if (StrUtil.isNotBlank(imsOrderDetail.getWarehousingId())){
                ImsWarehouse byId = imsWarehouseService.getById(imsOrderDetail.getWarehousingId());
                imsOrderDetail.setWareName(byId.getWareName());
            }
        }


        result.setHeader(imsOrderHeader);
        result.setRecordList(list);

        return result;
    }

    @Override
    public ImsOrderHeader queryEntity(String id) {
        ImsOrderHeader imsOrderHeader = this.getById(id);
        if(ObjectUtil.isEmpty(imsOrderHeader)) {
            throw new CommonException("出入库单据头不存在，id值为：{}", id);
        }
        return imsOrderHeader;
    }

    /**
     * 保存
     *
     * @param imsOrderAddParam
     */
    @Override
    @Transactional
    public synchronized void save(ImsOrderAddParam imsOrderAddParam) {
        ImsOrderHeader billHeader = imsOrderAddParam.getHeader();
        List<ImsOrderDetail> imsOrderDetails = imsOrderAddParam.getRecordList();
        // 不保存id
        billHeader.setBillId(null);
        // TODO 单据状态
        billHeader.setBillStatus("1");
        imsOrderHeaderService.save(billHeader);
        imsOrderDetails.forEach(imsOrderDetail -> {
            imsOrderDetail.setSystematicId(null);
            imsOrderDetail.setBillId(billHeader.getBillId());
        });


        // 手动插入主键
        for (ImsOrderDetail imsOrderDetail : imsOrderDetails) {
            imsOrderDetail.setBillId(billHeader.getBillId());
        }
        // 单据和单据明细保存
        imsOrderDetailService.saveBatch(imsOrderDetails);
    }


    @Override
    public String getBillNo(String billType) {
        // 生成规则 类型+日期+流水号
        String enBillType = "";
        switch (billType) {
            case "销售报价":
                enBillType = "XSBJ";
                break;
            case "销售订单":
                enBillType = "XSDD";
                break;
            case "销售出库":
                enBillType = "XSCK";
                break;


            case "采购申请":
                enBillType = "XSSQ";
                break;
            case "采购订单":
                enBillType = "CGDD";
                break;
            case "采购入库":
                enBillType = "CGRK";
                break;


            case "盘亏出库":
                enBillType = "FXCK";
                break;
            case "退货入库":
                enBillType = "THRK";
                break;
            case "盘盈入库":
                enBillType = "CXRK";
                break;
            case "库存盘点":
                enBillType = "KCPD";
                break;
        }
        String resultStr = "";
        switch (billType) {
            case "销售报价":
            case "销售订单":
            case "采购申请":
            case "采购订单":
                long count = imsOrderHeaderService.lambdaQuery()
                        .eq(ImsOrderHeader::getBillType, billType)
                        .count() + 1;
                resultStr = enBillType + "-" + DateUtil.format(new Date(), "yyyyMMdd") + "-" + count;
                break;
                case "销售出库":
                case "采购入库":
                case "盘亏出库":
                case "退货入库":
                case "盘盈入库":
                    long count1 = imsBillHeaderServiceImpl.lambdaQuery()
                            .eq(ImsBillHeader::getBillType, billType)
                            .count() + 1;
                    resultStr = enBillType + "-" + DateUtil.format(new Date(), "yyyyMMdd") + "-" + count1;
                    break;
            case "库存盘点":
                long count2 = imsInventoryCheckServiceImpl.lambdaQuery()
                        .eq(ImsInventoryCheck::getBillType, billType)
                        .count() + 1;
                resultStr = enBillType + "-" + DateUtil.format(new Date(), "yyyyMMdd") + "-" + count2;
                break;
        }
        return  resultStr;
    }
}
